//
//  ViewController.swift
//  test
//
//  Created by 火星人 on 2017/7/29.
//  Copyright © 2017年 火星人. All rights reserved.
//

import UIKit
import QSExtensionSwift


class ViewController: UIViewController, UICollectionViewDelegate, UICollectionViewDataSource {

    
    @IBOutlet weak var collectionView: MyCollectionView!
    
    var models = [UIColor]()
    
    override func viewDidLoad() {
        super.viewDidLoad()
        
        collectionView.dataSource = self
        
        collectionView.register(MyCollectionViewCell.classForCoder(), forCellWithReuseIdentifier:"MyCollectionViewCell")
        
        for _ in 1 ... 100 {
            models.append(UIColor.randomColor())
        }
        
        
        
    }
    
    func numberOfSections(in collectionView: UICollectionView) -> Int {
        return 1
    }
    
    func collectionView(_ collectionView: UICollectionView, numberOfItemsInSection section: Int) -> Int {
        return 100
    }
    
    func collectionView(_ collectionView: UICollectionView, cellForItemAt indexPath: IndexPath) -> UICollectionViewCell {
        
        let cell = collectionView.dequeueReusableCell(withReuseIdentifier: "MyCollectionViewCell", for: indexPath)
        
        cell.backgroundColor = models[indexPath.row]
        
        return cell
    }
    
}

class MyCollectionView: UICollectionView, UICollectionViewDelegate {
    
    lazy var layout = MyLayout()
    
    override init(frame: CGRect, collectionViewLayout layout: UICollectionViewLayout) {
        super.init(frame: frame, collectionViewLayout: layout)
        setup()
    }
    
    required init?(coder aDecoder: NSCoder) {
        super.init(coder: aDecoder)
        setup()
    }
    
    private func setup(){
        self.isScrollEnabled = false
        self.collectionViewLayout = layout
        
        self.delegate = self
        
        DispatchQueue.main.asyncAfter(deadline: DispatchTime.now() + Double(Int64(0.01 * Double(NSEC_PER_SEC))) / Double(NSEC_PER_SEC)) {
            [weak self] in
            
            let x = self!.layout.pageOffset * 49
            let rect = CGRect(x: x, y: 0, width: self!.layout.w, height: self!.layout.h)
            self?.scrollRectToVisible(rect, animated: false)
            
            DispatchQueue.main.asyncAfter(deadline: DispatchTime.now() + Double(Int64(0.05 * Double(NSEC_PER_SEC))) / Double(NSEC_PER_SEC)) {
                [weak self] in
                let indexPath = IndexPath(row: 50, section: 0)
                self?.layout.selectItemAt(indexPath)
            }
        }
        
    }
    
    func collectionView(_ collectionView: UICollectionView, didSelectItemAt indexPath: IndexPath) {
        layout.selectItemAt(indexPath)
    }
    
}

class MyCollectionViewCell: UICollectionViewCell {
    
}


class MyLayout: UICollectionViewLayout {
    
    
    private var layoutAttributes: [UICollectionViewLayoutAttributes] = []
    var number = 0
    var ratio: CGFloat = 0.7
    var w = 0.f
    var h = 0.f
    var pageOffset = 0.f
    var curSelected = -1
    
    override func prepare() {
        layoutAttributes.removeAll()
        
        w = self.collectionView!.width
        h = self.collectionView!.height
        pageOffset = w * (1 - ratio * ratio) * 0.5
        
        if let collectionView = self.collectionView {
            number = collectionView.numberOfItems(inSection: 0)
            let offsetX = collectionView.contentOffset.x
            
            let from = curSelected >= 0 ? curSelected - 2 : 0
            let to  = curSelected >= 0 ? curSelected + 2 : number
            let maxR = 1 / ratio
            let minR = 1.f
            let ww = w * ratio * ratio
            let ww2 = w * ratio * ratio * 0.5
            let more = maxR - 1
            
            for i in from ... to {
                if i < 0 || i == number {
                    continue
                }
                let indexPath = IndexPath(row: i, section: 0)
                let attr = layoutAttributesForItem(at: indexPath)
                
                let centerX = ww2 + pageOffset * indexPath.row.f
                attr?.center = CGPoint(x: centerX, y: h * 0.5)
                let d = abs(offsetX + w * 0.5 - centerX)
                var r = 1 + (1 - d / (w * 0.5 - ww2)) * more
                
                if r > maxR {
                    r = maxR
                }
                else if r < minR {
                    r = minR
                }
                
                attr?.size = CGSize(width: ww * r, height: h * ratio * r)
                layoutAttributes.append(attr!)
            }
        }
    }
    
    override func layoutAttributesForElements(in rect: CGRect) -> [UICollectionViewLayoutAttributes]? {
        return layoutAttributes
    }
    
    func selectItemAt(_ indexPath: IndexPath){
        
        curSelected = indexPath.row
        
        let x = pageOffset * (indexPath.row - 1).f
        let rect = CGRect(x: x, y: 0, width: w, height: h)
        self.collectionView?.scrollRectToVisible(rect, animated: true)
        let cur = indexPath.row
        if cur > 0 {
            let ip = IndexPath(row: cur - 1, section: 0)
            let cell = collectionView?.cellForItem(at: ip)
            if let cell = cell {
                collectionView?.bringSubview(toFront: cell)
            }
        }
        
        if cur < number - 1 {
            let ip = IndexPath(row: cur + 1, section: 0)
            let cell = collectionView?.cellForItem(at: ip)
            if let cell = cell {
                collectionView?.bringSubview(toFront: cell)
            }
        }
        let indexPath = IndexPath(row: cur, section: 0)
        let cell = collectionView?.cellForItem(at: indexPath)
        if let cell = cell {
            self.collectionView?.bringSubview(toFront: cell)
        }
    }
    
    override func layoutAttributesForItem(at indexPath: IndexPath) -> UICollectionViewLayoutAttributes? {
        let attr = UICollectionViewLayoutAttributes(forCellWith: indexPath)
        return attr
    }
    
    override func shouldInvalidateLayout(forBoundsChange newBounds: CGRect) -> Bool {
        return true
    }
    
    override var collectionViewContentSize: CGSize {
        return CGSize(width: self.collectionView!.width + pageOffset * (number - 2).f, height: self.collectionView!.height)
    }
    
}



